﻿#include "tcpclientfrm.h"
#include "ui_tcpclientfrm.h"

#include <QDateTime>
#include <QHostAddress>
#include <QMetaEnum>
#include <QNetworkInterface>

#include <net/netwriting.h>
#include <net/tcpclient.h>
QNET_USING_NAMESPACE

TcpClientFrm::TcpClientFrm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TcpClientFrm)
{
    ui->setupUi(this);
    m_client = Q_NULLPTR;
    m_session = Q_NULLPTR;

    QList<QHostAddress> iplist = QNetworkInterface::allAddresses();  //
    foreach(auto host, iplist)
    {
        if(host.protocol() == QAbstractSocket::IPv6Protocol)
        {
            continue;
        }
        ui->comboBoxLocalAddr->addItem(host.toString());
        if(host.isLoopback())
        {
            ui->comboBoxLocalAddr->setCurrentText(host.toString());
        }
    }
}

TcpClientFrm::~TcpClientFrm()
{
    if(m_client)
    {
        m_client->deleteLater();
        m_client = Q_NULLPTR;
    }
    delete ui;
}

void TcpClientFrm::onStateChanged(TcpSession *session, bool connected)
{
    QString msg = QString(tr("检测到%1:%2")).arg(session->remoteIp().toString())
            .arg(session->remotePort());
    if(connected)
    {
        m_session = session;
        m_session->setReading(this);
        msg.append(tr(" 连接成功"));
    }else {
        m_session = Q_NULLPTR;
        msg.append(tr(" 连接断开"));
    }
    logAppend(msg);
}

void TcpClientFrm::onError(QAbstractSocket::SocketError error)
{
    QString msg;
    QTextStream stream(&msg);
    QMetaEnum metaEnum = QMetaEnum::fromType<QAbstractSocket::SocketError>();
    //枚举值转字符串
    stream << tr("检测到socket错误信息：") << metaEnum.valueToKey(error);
    logAppend(msg);
}

void TcpClientFrm::onProc(const QByteArray &arry)
{
    QString msg  = QString(tr(" 接收到(%1字节)数据:%2"))
            .arg(arry.size())
            .arg(QString::fromUtf8(arry));
    logAppend(msg);
}

void TcpClientFrm::setStopEnable(bool enabled)
{
    ui->btnSendData->setEnabled(enabled);
    ui->btnConnect->setEnabled(!enabled);
    ui->btnStop->setEnabled(enabled);
}

void TcpClientFrm::on_btnConnect_clicked()
{
    QString localAddr = ui->comboBoxLocalAddr->currentText();
    QHostAddress localHost(localAddr);

    quint16 localPort = quint16(ui->spinLocalPort->value());

    QString addr = ui->eidtDstAddr->text();
    QHostAddress dstAddr(addr);
    quint16 dstPort = quint16(ui->spinDstPort->value());
    bool isReconnect = ui->checkBoxReconnect->isChecked();
    if(m_client){
        m_client->disconnected();
        m_client->deleteLater();
    }
    m_client = new TcpClient(this );
    m_client->setAutoReconnect(isReconnect);
    if(!m_client->bind(localHost, localPort))
    {
        logAppend(tr("客户端绑定本机地址失败。"));
        return ;
    }
    m_client->connect(dstAddr, dstPort);
    logAppend(tr("完成客户端启动。"));

    setStopEnable(true);
}

void TcpClientFrm::on_btnStop_clicked()
{
    if(m_client)
    {
        m_client->disconnected();
        m_client->deleteLater();
        m_client = Q_NULLPTR;
        logAppend(tr("客户端已停止。"));
    }
    setStopEnable(false);
}

void TcpClientFrm::logAppend(QString msg)
{
    QString tmp = msg;
    tmp.insert(0, QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz "));

    ui->textBrowserLog->append(tmp);
}

void TcpClientFrm::on_checkBoxReconnect_stateChanged(int arg1)
{
    Q_UNUSED(arg1)
    if(m_client)
    {
        bool isReconnect = ui->checkBoxReconnect->isChecked();
        m_client->setAutoReconnect(isReconnect);
    }
}

void TcpClientFrm::on_btnClear_clicked()
{
    ui->textBrowserLog->clear();
}

void TcpClientFrm::on_btnSendData_clicked()
{
    QString msg;
    if(m_session)
    {
        QString sendText = ui->textEditSend->toPlainText();
        if(sendText.isEmpty())
        {
            msg = QString(tr("待发送的数据不能为空。"));
        }else {

            QByteArray sendArray = sendText.toUtf8();
            QSharedPointer<NetWriting> writing(new NetWriting(sendArray), &QObject::deleteLater);
            connect(writing.data(), &NetWriting::fulfil, this, &TcpClientFrm::fulfil_slot);
            if(m_session->write(writing))
            {
                msg = QString(tr("数据加入队列成功。"));
            }else{
                msg = QString(tr("数据加入队列失败。"));
            }
        }
    }else {
        msg = QString(tr("未连接，无法发送数据。"));
    }
    logAppend(msg);
}

void TcpClientFrm::on_btnClearSendData_clicked()
{
    ui->textEditSend->clear();
}

void TcpClientFrm::fulfil_slot(QSharedPointer<NetWriting> owner, int size)
{
    QString msg  = QString(tr("原始数据%1字节。 发送。"))
                           .arg(owner->size());

    QTextStream stream(&msg);
    if(size < 0)
    {
        stream << tr("失败！");
    }else {
        stream << tr("成功！");
    }
    logAppend(msg);
    ui->labSendSize->setNum(size);
}
